<template>
  <div class="container">
    <div class="upload-container">
      <input type="file" ref="input" @change="handleUpdate" draggable multiple>
    </div>
    <div class="fileList">
      <h2>上传的文件列表</h2>
      <ul>
        <li v-for="item in fileList">{{item.name}}--{{item.size}}</li>
      </ul>
    </div>
  </div>
</template>

<script setup>
import SparkMD5 from 'spark-md5'
import {ref} from "vue";
import axios from "axios";

const fileList = ref([])

const input = ref(null)
async function handleUpdate() {
  // 创建分片
  const files = input.value.files;
  fileList.value= files
  console.log(1111111111)
  console.log("fileList.value")
  console.log(fileList.value)
  let chunks =  createChunk(files[0],50 * 1024 * 1024)
  console.log(chunks)
  // 文件内容创建hash
   let ChunkHash = await createHash(chunks);
  // 调用发送分片的接口
  uploadChunk(chunks,ChunkHash,files[0].name)
}

/**
 * 创建分片数据
 */

function createChunk(file,chunkSize){
  const result = [] // 分片结果
  for (let i = 0; i < file.size; i += chunkSize) {
    result.push(file.slice(i, i + chunkSize)) // 添加到结果中
  }
  return result;
}

/**
 * 根据文件内容创建hash值
  */
function createHash(chunks) {
  return new Promise((resolve) => {
    let spark = new SparkMD5()
    // 递归
     function _read(i) {
      if (i >= chunks.length) {
        resolve(spark.end())
        return;
      }
      let blob = chunks[i] // 获取其中的一个片段
      // 创建一个FIleReader对象
      let reader = new FileReader();
      reader.onloadend = function (e) {
          let bytes = e.target.result;
          spark.append(bytes);
          _read(i + 1)
      }
      reader.readAsArrayBuffer(blob)
    }
    _read(0)
  })
}

/**
 * 分片上传
 */

function uploadChunk(chunks,hash,fileName) {
  // 文件怎么样传给后端
  let task = []
  chunks.forEach((chunk,index) => {
    let formData = new FormData();
    formData.append('chunk',chunk)
    formData.append('chunkName',`${hash}-${index}-${fileName}`)
    formData.append('fileName',fileName)
    let promise = axios.post("http://localhost:3000/updateFile",formData,{
      headers: {'Content-Type': 'multipart/form-data'}
    });
    task.push(promise)
  })
  // 所有分片上传成功后，我们需要有一个通知告诉后端已经上传完成
  Promise.all(task).then(() => {
    console.log("文件上传成功")
    console.log("通知后端")
  })
}


</script>


<style lang="scss" scoped>
.container {
  .upload-container{
    width: 100%;
    height: 300px;
    border: 1px dashed #ccc;
    display: flex;
    justify-content: center;
    align-items: center;

    input{
      width: 100%;
      height: 100%;
    }
  }
}

.fileList ul{
  width: 100%;
}
</style>
